package com.fishingwithme.infrastructure.cfg;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.fishingwithme.infrastructure.CustomAuthenticationEntryPoint;
import com.fishingwithme.infrastructure.JwtTokenFilter;
import com.fishingwithme.infrastructure.UsernamePasswordAuthenticationProvider;
import com.fishingwithme.infrastructure.UsernamePasswordLoginFilter;
import com.fishingwithme.infrastructure.WeChatAuthenticationProvider;
import com.fishingwithme.infrastructure.WeChatLoginFailureHandler;
import com.fishingwithme.infrastructure.WeChatLoginFilter;
import com.fishingwithme.infrastructure.WeChatLoginSuccessHandler;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    private final WeChatAuthenticationProvider weChatAuthenticationProvider;
    private final UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider;
    private final JwtTokenFilter jwtTokenFilter;

    public SecurityConfig(WeChatAuthenticationProvider weChatAuthenticationProvider,
                          UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider,
                          JwtTokenFilter jwtTokenFilter) throws Exception {
        this.weChatAuthenticationProvider = weChatAuthenticationProvider;
        this.usernamePasswordAuthenticationProvider = usernamePasswordAuthenticationProvider;
        this.jwtTokenFilter = jwtTokenFilter;
    }


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        Customizer<RequestCacheConfigurer<HttpSecurity>> customizer = Customizer.withDefaults();
        http

                .exceptionHandling(exception -> exception.authenticationEntryPoint(new CustomAuthenticationEntryPoint()))
                .requestCache(customizer)
                .csrf(AbstractHttpConfigurer::disable) // 禁用 CSRF
                .authorizeHttpRequests(authorize -> authorize  // 替换 authorizeRequests()
                        .requestMatchers("/user/loginwx", "/user/login", "/user/register","/spot/getUserSpot", "/public/**","common/agr*","circle-messages/**","/circle/getCircles","/circle/getCity","/circle/searchCities").permitAll()
//                        .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-ui.html", "/webjars/**").permitAll() // Allow Swagger access
                        .anyRequest().authenticated()
                );
                http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(weChatLoginFilter(), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(usernamePasswordLoginFilter(), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public WeChatLoginFilter weChatLoginFilter() throws Exception {
        WeChatLoginFilter filter = new WeChatLoginFilter();
        filter.setAuthenticationManager(authenticationManager());
        filter.setAuthenticationSuccessHandler(weChatLoginSuccessHandler());
        filter.setAuthenticationFailureHandler(weChatLoginFailureHandler());
        return filter;
    }

    @Bean
    public UsernamePasswordLoginFilter usernamePasswordLoginFilter() throws Exception {
        UsernamePasswordLoginFilter filter = new UsernamePasswordLoginFilter();
        filter.setAuthenticationManager(authenticationManager());
        filter.setAuthenticationSuccessHandler(weChatLoginSuccessHandler());
        filter.setAuthenticationFailureHandler(weChatLoginFailureHandler());
        return filter;
    }

    @Bean
    public AuthenticationSuccessHandler weChatLoginSuccessHandler() {
        return new WeChatLoginSuccessHandler();
    }

    @Bean
    public AuthenticationFailureHandler weChatLoginFailureHandler() {
        return new WeChatLoginFailureHandler();
    }


    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return new ProviderManager(Arrays.asList(weChatAuthenticationProvider, usernamePasswordAuthenticationProvider));
    }
}
